package model

import (
	"meeting-manager/global"
	"sync"
)

// Address 为服务器地址创建一个别名
type Address string

// Server 子服务器的信息
type Server struct {
	// 子服务的名称
	// 子服务注册时，在请求体需包含 name 字段，若该字段为空，则设置为 addr
	name string

	// 子服务器的地址
	// 在子服务器注册时，接收到请求的这一方会获取到对方的地址
	addr Address

	// 最大承载量与当前承载量
	// 计算方式为媒体流的数量（分上行和下行）
	maxLoad     int
	currentLoad int

	// 修改当前承载量时，需要加锁
	mutex *sync.RWMutex
}

func NewServer(name string, addr string, maxLoad int) *Server {
	return &Server{
		name:        name,
		addr:        Address(addr),
		maxLoad:     maxLoad,
		currentLoad: 0,
		mutex:       new(sync.RWMutex),
	}
}

// GetName 获取服务器的名称
func (server *Server) GetName() string {
	return server.name
}

// GetAddr 获取服务器的地址
func (server *Server) GetAddr() Address {
	return server.addr
}

// GetAvailableLoad 获取可用负载
// 可用负载是指总负载减去已占用负载，表示还能继续承受的负载，该值不能为负数
func (server *Server) GetAvailableLoad() int {
	server.mutex.RLock()
	defer server.mutex.RUnlock()

	return server.maxLoad - server.currentLoad
}

// AddLoad 增加载荷，表示有新会议被创建
func (server *Server) AddLoad(load int) bool {
	server.mutex.Lock()
	defer server.mutex.Unlock()

	// 判断可用负载是否足够
	if server.currentLoad+load > server.maxLoad {
		return false
	}

	server.currentLoad += load
	return true
}

// MinusLoad 减少载荷，表示有会议结束
func (server *Server) MinusLoad(load int) {
	server.mutex.Lock()
	defer server.mutex.Unlock()

	server.currentLoad -= load

	if server.currentLoad < 0 {
		global.Logger.Error(" available load of server " + server.name + "can not be negative")
	}
}
